namespace NHCodeFirst.FluentMapper
{
    using System;
    using Enums;
    using HbmModel;

    public class ComponentMapper<TComponent> : MemberMapper<TComponent, ComponentMapper<TComponent>>
    {
        private readonly Component component;

        internal ComponentMapper(Component component) : base(component)
        {
            this.component = component;
            child = this;
        }

        public ComponentMapper<TComponent> Lazy(bool value)
        {
            component.Lazy = value.ToString().ToLower();
            return this;
        }

        public ComponentMapper<TComponent> Access(Access access, Naming? namingStrategy = null)
        {
            return Access(access.ToString().ToLower(), namingStrategy);
        }

        public ComponentMapper<TComponent> Access<T>(Naming? namingStrategy = null)
        {
            return Access(typeof(T).FullName, namingStrategy);
        }

        public ComponentMapper<TComponent> Access(Type type, Naming? namingStrategy = null)
        {
            return Access(type.FullName, namingStrategy);
        }

        private ComponentMapper<TComponent> Access(string access, Naming? naming)
        {
            component.Access = access;
            if (naming.HasValue)
                component.Access += "." + EnumsToHbmString.GetAccessNamingStrategy(naming.Value);
            return this;
        }

        public ComponentMapper<TComponent> Insert(bool value)
        {
            component.Insert = value.ToString().ToLower();
            return this;
        }

        public ComponentMapper<TComponent> Update(bool value)
        {
            component.Update = value.ToString().ToLower();
            return this;
        }

        public ComponentMapper<TComponent> Unique(bool value)
        {
            component.Unique = value.ToString().ToLower();
            return this;
        }

        public ComponentMapper<TComponent> OptimisticLock(bool value)
        {
            component.OptimisticLock = value.ToString().ToLower();
            return this;
        }
    }
}